package edu.hawaii.kukui

import edu.hawaii.kukui.Activity
import net.sf.antcontrib.math.Math

class MyPageController {

  static navigation = true //[
  //[group:'tabs', action:'index', title: 'My Page', order: 100]
//]


  def authenticateService

  def userInfo = {
    def userPrincipal = authenticateService.principal()
    KukuiUser user = authenticateService.userDomain()
    return [userDetail: user]
  }

  def myActivities = {

  }

  /**
   * Default action for the myPage controller.
   */
  def index = {
    def userPrincipal = authenticateService.principal()
    //render userPrincipal?.getUsername()
    KukuiUser user = authenticateService.userDomain()
    def content = g.include(controller: 'myPage', action: 'userKukuiNutsTotal')


    def resultsTextAttempt = ActivityTextAttempt?.findAll("from edu.hawaii.kukui.ActivityTextAttempt at where at.activity.publicationDate <= now and now < at.activity.expirationDate and at.validateStatus = 'Selected' and at.kukuiUser.id =?", user.id)
    def resultsImageAttempt = ActivityImageAttempt?.findAll("from edu.hawaii.kukui.ActivityImageAttempt at where at.activity.publicationDate <= now and now < at.activity.expirationDate and at.validateStatus = 'Selected' and at.kukuiUser.id =?", user.id)
    def resultsCodeAttempt = ActivityCodeAttempt?.findAll("from edu.hawaii.kukui.ActivityCodeAttempt at where at.activity.publicationDate <= now and now < at.activity.expirationDate and at.validateStatus = 'Selected' and at.kukuiUser.id =?", user.id)
    def results = resultsTextAttempt.plus(resultsImageAttempt).plus(resultsCodeAttempt)

    return [userDetail: user, activitySelected: results, kukuiNutsTotal: content, roundTotals: content]
  }
  def availActivities = {
    KukuiUser user = authenticateService.userDomain()
    def userPrincipal = authenticateService.principal()
    //def currentAct = ActivityTextAttempt?.executeQuery("select at.id from edu.hawaii.kukui.ActivityTextAttempt at join at.kukuiUser ku where ku.id = ?", user.id)
    def resultsText = Activity?.findAll("from edu.hawaii.kukui.Activity a where a.publicationDate <= now and now < a.expirationDate and a.verificationType = 'Text_Field' and id not in (select aa.id from edu.hawaii.kukui.ActivityTextAttempt at join at.activity aa join at.kukuiUser ku where ku.id = ?)", user.id)
    def resultsImage = Activity?.findAll("from edu.hawaii.kukui.Activity a where a.publicationDate <= now and now < a.expirationDate and a.verificationType = 'Upload_Image' and id not in (select aa.id from edu.hawaii.kukui.ActivityImageAttempt at join at.activity aa join at.kukuiUser ku where ku.id = ?)", user.id)
    def resultsCode = Activity?.findAll("from edu.hawaii.kukui.Activity a where a.publicationDate <= now and now < a.expirationDate and a.verificationType = 'Confirmation_Code' and id not in (select aa.id from edu.hawaii.kukui.ActivityCodeAttempt at join at.activity aa join at.kukuiUser ku where ku.id = ?)", user.id)
    def results = resultsText.plus(resultsImage).plus(resultsCode)
    results.sort {it.eventDate}.reverse()
    return [activityInstanceList: results, activityInstanceTotal: Activity.count()]
  }

  def selectedActivities = {
    KukuiUser user = authenticateService.userDomain()
    def userPrincipal = authenticateService.principal()
    //def currentAct = ActivityTextAttempt?.executeQuery("select at.id from edu.hawaii.kukui.ActivityTextAttempt at join at.kukuiUser ku where ku.id = ?", user.id)
    //def resultsText1 = ActivityTextAttempt?.executeQuery
    //def resultsText = ActivityTextAttempt.list(params)
    //def resultsText = ActivityTextAttempt.get(3)
    def resultsText = ActivityTextAttempt.findAll("from edu.hawaii.kukui.ActivityTextAttempt at where at.validateStatus = 'Selected' and at.kukuiUser.id = ?", user.id)
    def resultsImage = ActivityImageAttempt.findAll("from edu.hawaii.kukui.ActivityImageAttempt at where at.validateStatus = 'Selected' and at.kukuiUser.id = ?", user.id)
    def resultsCode = ActivityCodeAttempt.findAll("from edu.hawaii.kukui.ActivityCodeAttempt at join at.activity join at.kukuiUser ku where ku.id = ?", user.id)
    //def resultsText = Activity?.findAll("from edu.hawaii.kukui.Activity a where a.publicationDate <= now and now < a.expirationDate and id in (select aa.id from edu.hawaii.kukui.ActivityTextAttempt at join at.activity aa join at.kukuiUser ku where ku.id = ? and at.validateStatus = 'Selected')", user.id)
    //def resultsImage = Activity?.findAll("from edu.hawaii.kukui.Activity a where a.publicationDate <= now and now < a.expirationDate and id in (select aa.id from edu.hawaii.kukui.ActivityImageAttempt at join at.activity aa join at.kukuiUser ku where ku.id = ? and at.validateStatus = 'Selected')", user.id)
    //def resultsCode = Activity?.findAll("from edu.hawaii.kukui.Activity a where a.publicationDate <= now and now < a.expirationDate and id in (select aa.id from edu.hawaii.kukui.ActivityCodeAttempt at join at.activity aa join at.kukuiUser ku where ku.id = ? and at.validateStatus = 'Selected')", user.id)
    def results = resultsText.plus(resultsImage) //.plus(resultsCode)
    //def results = ActivityTextAttempt.findAll("from edu.hawaii.kukui.ActivityTextAttempt at join at.activity aa join at.kukuiUser ku where ku.id = ? and at.validateStatus = 'Selected'", user.id)
    //results.sort {it.activity.eventDate}.reverse()
    return [activityAttemptInstanceList: results, activityAttemptInstanceTotal: resultsText.count()]

  }

  def submittedActivities = {

    KukuiUser user = authenticateService.userDomain()
    def userPrincipal = authenticateService.principal()
    //def currentAct = ActivityTextAttempt?.executeQuery("select at.id from edu.hawaii.kukui.ActivityTextAttempt at join at.kukuiUser ku where ku.id = ?", user.id)

    def resultsTextAttempt = ActivityTextAttempt?.findAll("from edu.hawaii.kukui.ActivityTextAttempt at where at.activity.publicationDate <= now and now < at.activity.expirationDate and at.validateStatus = 'Submitted' and at.kukuiUser.id =?", user.id)
    def resultsImageAttempt = ActivityImageAttempt?.findAll("from edu.hawaii.kukui.ActivityImageAttempt at where at.activity.publicationDate <= now and now < at.activity.expirationDate and at.validateStatus = 'Submitted' and at.kukuiUser.id =?", user.id)
    def resultsCodeAttempt = ActivityCodeAttempt?.findAll("from edu.hawaii.kukui.ActivityCodeAttempt at where at.activity.publicationDate <= now and now < at.activity.expirationDate and at.validateStatus = 'Submitted' and at.kukuiUser.id =?", user.id)
    def results = resultsTextAttempt.plus(resultsImageAttempt).plus(resultsCodeAttempt)

    return [activityInstanceList: results]

  }

  def awardedActivities = {

    KukuiUser user = authenticateService.userDomain()
    def userPrincipal = authenticateService.principal()
    def currentAct = ActivityTextAttempt?.executeQuery("select at.id from edu.hawaii.kukui.ActivityTextAttempt at join at.kukuiUser ku where ku.id = ?", user.id)
    def resultsText = Activity?.findAll("from edu.hawaii.kukui.Activity a where a.publicationDate <= now and now < a.expirationDate and id in (select aa.id from edu.hawaii.kukui.ActivityTextAttempt at join at.activity aa join at.kukuiUser ku where ku.id = ? and at.validateStatus = 'Awarded')", user.id)
    def resultsImage = Activity?.findAll("from edu.hawaii.kukui.Activity a where a.publicationDate <= now and now < a.expirationDate and id in (select aa.id from edu.hawaii.kukui.ActivityImageAttempt at join at.activity aa join at.kukuiUser ku where ku.id = ? and at.validateStatus = 'Awarded')", user.id)
    def resultsCode = Activity?.findAll("from edu.hawaii.kukui.Activity a where a.publicationDate <= now and now < a.expirationDate and id in (select aa.id from edu.hawaii.kukui.ActivityCodeAttempt at join at.activity aa join at.kukuiUser ku where ku.id = ? and at.validateStatus = 'Awarded')", user.id)
    def results = resultsText.plus(resultsImage).plus(resultsCode)
    return [activityInstanceList: results, activityInstanceTotal: Activity.count()]

  }

  def declinedActivities = {

    KukuiUser user = authenticateService.userDomain()
    //def availAct = Activity.list()
    def userPrincipal = authenticateService.principal()
    def resultsText = Activity?.findAll("from edu.hawaii.kukui.Activity a where a.publicationDate <= now and now < a.expirationDate and id in (select aa.id from edu.hawaii.kukui.ActivityTextAttempt at join at.activity aa join at.kukuiUser ku where ku.id = ? and at.validateStatus = 'Declined')", user.id)
    def resultsImage = Activity?.findAll("from edu.hawaii.kukui.Activity a where a.publicationDate <= now and now < a.expirationDate and id in (select aa.id from edu.hawaii.kukui.ActivityImageAttempt at join at.activity aa join at.kukuiUser ku where ku.id = ? and at.validateStatus = 'Declined')", user.id)
    def resultsCode = Activity?.findAll("from edu.hawaii.kukui.Activity a where a.publicationDate <= now and now < a.expirationDate and id in (select aa.id from edu.hawaii.kukui.ActivityCodeAttempt at join at.activity aa join at.kukuiUser ku where ku.id = ? and at.validateStatus = 'Declined')", user.id)
    def results = resultsText.plus(resultsImage).plus(resultsCode)
    return [activityInstanceList: results, activityInstanceTotal: Activity.count()]

  }

  def image_r = {
    KukuiUser user = authenticateService.userDomain()
    def i = KukuiUserPicture.get(user.id)
    byte[] imagepic = i.userPicture
    //response.contentType = "image/jpeg"
    //response.setContentLength(i.picture.length)
    //response.outputStream.write(userImage.picture)
    //response.setHeader( "Content-Type", "image/png")
    response.outputStream << imagepic
    //response.outputStream.flush()
  }

  def imageAttempt = { imageAttemptId ->

    def imageAttempt = ActivityImageAttempt.get(imageAttemptId)
    byte[] imagepic = imageAttempt.activityImage
    //response.contentType = "image/jpeg"
    //response.setContentLength(i.picture.length)
    //response.outputStream.write(userImage.picture)
    //response.setHeader( "Content-Type", "image/png")
    response.outputStream << imagepic
    //response.outputStream.flush()
  }




  def showActivity = {
    def activityInstance = Activity.get(params.id)
    if (!activityInstance) {
      flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'activity.label', default: 'Activity'), params.id])}"
      redirect(action: "list")
    }
    else {
      [activityInstance: activityInstance]
    }
  }

  def awardedActivity = {
    //def availAct = Activity.list()

    //def activityInstanceList = Activity.list()
    def results = ActivityImageAttempt.findAllByValidateStatus("Awarded")
    params.max = Math.min(params.max ? params.int('max') : 10, 100)
    return [activityAwInstanceList: results, activityAwInstanceTotal: Activity.count()]
    //[activityInstanceList: Activity.list(), activityInstanceTotal: Activity.count()]
  }

  def pendingActivity = {
    //def availAct = Activity.list()

    //def activityInstanceList = Activity.list()
    def results = ActivityTextAttempt.findAllByValidateStatus("Pending")
    params.max = Math.min(params.max ? params.int('max') : 10, 100)
    return [activityPeInstanceList: results, activityPeInstanceTotal: Activity.count()]
    //[activityInstanceList: Activity.list(), activityInstanceTotal: Activity.count()]
  }

  def list = {
    params.max = Math.min(params.max ? params.int('max') : 10, 100)
    [activityImageAttemptInstanceList: ActivityImageAttempt.list(params), activityImageAttemptInstanceTotal: ActivityImageAttempt.count()]
  }

  def newActivityAttempt = {
    def results = Activity?.findAll("from edu.hawaii.kukui.")

  }

  def saveActivityAttempt = {

  }

  def editActivityAttempt = {

  }

  def saveNewImageAttempt = {

    KukuiUser user = authenticateService.userDomain()
    def activityImageAttemptInstance = new ActivityImageAttempt(activity:
    Activity.get(params.id), kukuiUser: KukuiUser.get(user.id),
            activityImage: " ", selectTimestamp: new Date(),
            submitTimestamp: new Date(0), validateTimestamp: new Date(0),
            validateStatus: "Selected", validateComment: " ", imageCaption: " ",
            noteToAdmin: "")

    if (activityImageAttemptInstance.save()) {
      flash.message = "${activityImageAttemptInstance.activity} :: Saved activity as selected."
      redirect(action: "myActivities", id: activityImageAttemptInstance.id)
    }
    else {
      flash.message = activityImageAttemptInstance.errors
      redirect(action: "myActivities", id: activityImageAttemptInstance.id)
    }
  }

  def saveNewCodeAttempt = {

    KukuiUser user = authenticateService.userDomain()
    def activityCodeAttemptInstance = new ActivityCodeAttempt(activity:
    Activity.get(params.id), kukuiUser: KukuiUser.get(user.id),
            verificationCode: "", selectTimestamp: new Date(),
            submitTimestamp: new Date(0), validateTimestamp: new Date(0),
            validateStatus: "Selected", validateComment: " ",
            noteToAdmin: "")

    if (activityCodeAttemptInstance.save()) {
      flash.message = "${activityCodeAttemptInstance.activity} :: Saved activity as selected."
      redirect(action: "myActivities", id: activityCodeAttemptInstance.id)
    }
    else {
      flash.message = activityCodeAttemptInstance.errors
      redirect(action: "myActivities", id: activityCodeAttemptInstance.id)
    }
  }

  def saveNewTextAttempt = {

    KukuiUser user = authenticateService.userDomain()
    def textQa = ActivityVerificationText.findAll("from ActivityVerificationText avt join avt.activity a where a.id = ? ", Long.parseLong(params.id))
    def randomQa
    if (textQa.size() > 0) {
      def randomIdx = new Random().nextInt(textQa.size())
      randomQa = textQa[randomIdx]


      def activityTextAttemptInstance = new ActivityTextAttempt(activity: Activity.get(params.id),
              kukuiUser: KukuiUser.get(user.id), verificationText: " ", selectTimestamp: new Date(),
              submitTimestamp: new Date(0), validateTimestamp: new Date(0),
              activityVerificationText: ActivityVerificationText.list()[randomIdx],
              validateStatus: "Selected", validateComment: " ", noteToAdmin: "")

      if (activityTextAttemptInstance.save()) {
        flash.message = "${activityTextAttemptInstance.activity} :: Saved activity as selected."
        redirect(action: "myActivities", id: activityTextAttemptInstance.id)
      }
      else {
        flash.message = activityTextAttemptInstance.errors
        redirect(action: "myActivities", id: activityTextAttemptInstance.id)
      }
    }
    else {
      flash.message = "Error: verification questions not available."
      redirect(action: "myActivities")

    }
  }



  def createActivityAttempt = {
    def activityTextAttemptInstance = new ActivityTextAttempt()
    activityTextAttemptInstance.properties = params
    return [activityTextAttemptInstance: activityTextAttemptInstance]
  }

  def activityTextEdit = {
    def activityTextAttemptInstance = ActivityTextAttempt.get(params.id)
    if (!activityTextAttemptInstance) {
      flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'activityTextAttempt.label', default: 'ActivityTextAttempt'), params.id])}"
      redirect(action: "list")
    }
    else {
      return [activityTextAttemptInstance: activityTextAttemptInstance]
    }
  }

  def activityImageEdit = {
    def activityImageAttemptInstance = ActivityImageAttempt.get(params.id)
    if (!activityImageAttemptInstance) {
      flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'activityImageAttempt.label', default: 'ActivityImageAttempt'), params.id])}"
      redirect(action: "list")
    }
    else {
      return [activityImageAttemptInstance: activityImageAttemptInstance]
    }
  }
  def activityCodeEdit = {
    def activityCodeAttemptInstance = ActivityCodeAttempt.get(params.id)
    if (!activityCodeAttemptInstance) {
      flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'activityCodeAttempt.label', default: 'ActivityCodeAttempt'), params.id])}"
      redirect(action: "list")
    }
    else {
      return [activityImageAttemptInstance: activityImageAttemptInstance]
    }
  }

  /**
   * Update activity text attempt record. Used primarily for updaing "selected" text attempt activities.
   */
  def activityTextUpdate = {
    def activityTextAttemptInstance = ActivityTextAttempt.get(params.id)
    if (activityTextAttemptInstance) {
      if (params.version) {
        def version = params.version.toLong()
        if (activityTextAttemptInstance.version > version) {
          activityTextAttemptInstance.errors.rejectValue("version", "default.optimistic.locking.failure", [message(code: 'activityTextAttempt.label', default: 'ActivityTextAttempt')] as Object[], "Another user has updated this ActivityTextAttempt while you were editing")
          redirect(action: "myActivities", id: activityTextAttemptInstance.id)
          //render(view: "myActivities", model: [activityTextAttemptInstance: activityTextAttemptInstance])
          return
        }
      }
      activityTextAttemptInstance.properties = params
      activityTextAttemptInstance.validateStatus = "Submitted"
      if (!activityTextAttemptInstance.hasErrors() && activityTextAttemptInstance.save(flush: true)) {
        flash.message = "${activityTextAttemptInstance.activity.title} Submitted"
        redirect(action: "myActivities")
      }
      else {
        render(view: "edit", model: [activityTextAttemptInstance: activityTextAttemptInstance])
      }
    }
    else {
      flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'activityTextAttempt.label', default: 'ActivityTextAttempt'), params.id])}"
      redirect(action: "myActivitiest")
    }
  }

  /**
   * Returns kukuiNut totals for current user.
   */
  def userKukuiNutsTotal = {
    KukuiUser user = authenticateService.userDomain()
    def userPrincipal = authenticateService.principal()
    def roundTotals = []
    def intervals = CompetitionIntervals.findAll()
    intervals.each {
      def temp = new Expando()
      temp.title = it.title
      def tempStartDate = it.startDate
      def tempEndDate = it.endDate
      def actTextTotal = ActivityTextAttempt.executeQuery("select sum(at.activity.kukuiNuts) from edu.hawaii.kukui.ActivityTextAttempt at where at.validateTimestamp between ? and ? and at.kukuiUser.id = ?", [it.startDate, it.endDate, user.id])
      Integer tempInt = 0

      if (!(actTextTotal == [null])) {
        tempInt += actTextTotal
      }
      temp.kukuiNutsTotal = tempInt

      roundTotals.add(temp)
    }
    //def results = ActivityTextAttempt.executeQuery("select new map(at.kukuiUser.building as building, at.kukuiUser.floor as floor, sum(at.activity.kukuiNuts) as sum) from edu.hawaii.kukui.ActivityTextAttempt at group by at.kukuiUser.building, at.kukuiUser.floor")
    //def buildingResults = new Expando()
    return [roundTotals: roundTotals]
  }

  def updateProfilePic = {
    def kukuiUserPictureInstance = KukuiUserPicture.get(params.id)
    if (kukuiUserPictureInstance) {
      if (params.version) {
        def version = params.version.toLong()
        if (kukuiUserPictureInstance.version > version) {

          kukuiUserPictureInstance.errors.rejectValue("version", "default.optimistic.locking.failure", [message(code: 'kukuiUserPicture.label', default: 'KukuiUserPicture')] as Object[], "Another user has updated this KukuiUserPicture while you were editing")
          render(view: "edit", model: [kukuiUserPictureInstance: kukuiUserPictureInstance])
          return
        }
      }
      kukuiUserPictureInstance.properties = params
      if (!kukuiUserPictureInstance.hasErrors() && kukuiUserPictureInstance.save(flush: true)) {
        flash.message = "${message(code: 'default.updated.message', args: [message(code: 'kukuiUserPicture.label', default: 'KukuiUserPicture'), kukuiUserPictureInstance.id])}"
        redirect(action: "show", id: kukuiUserPictureInstance.id)
      }
      else {
        render(view: "edit", model: [kukuiUserPictureInstance: kukuiUserPictureInstance])
      }
    }
    else {
      flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'kukuiUserPicture.label', default: 'KukuiUserPicture'), params.id])}"
      redirect(action: "list")
    }
  }

}
